import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        // 1、创建stream
        Stream<String> stream = Stream.of("A", "B", "C", "D");
        Stream<String> stream1 = Arrays.stream(new String[] { "A", "B", "C" });
        Stream<String> stream2 = List.of("X", "Y", "Z").stream();
        stream.forEach(System.out::println);
        stream1.forEach(System.out::println);
        stream2.forEach(System.out::println);

        // 2、创建Stream还可以通过Stream.generate()方法，它需要传入一个Supplier对象：
        // Supplier创建的Stream会不断调用Supplier.get()方法来不断产生下一个元素
        Stream<Integer> natual = Stream.generate(new NatualSupplier());
        // 注意：无限序列必须先变成有限序列再打印:
        natual.limit(20).forEach(System.out::println);
        // 创建Stream的第三种方法是通过一些API提供的接口，直接获得Stream。
        // 例如，Files类的lines()方法可以把一个文件变成一个Stream，每个元素代表文件的一行内容：
        // try (Stream<String> lines = Files.lines(Paths.get("/path/to/file.txt"))) {
        // ...
        // }

        // 另外，正则表达式的Pattern对象有一个splitAsStream()方法，可以直接把一个长字符串分割成Stream序列而不是数组：
        Pattern p = Pattern.compile("\\s+");
        Stream<String> s = p.splitAsStream("The quick brown fox jumps over the lazy dog");
        s.forEach(System.out::println);

        // 因为Java的泛型不支持基本类型，所以我们无法用Stream<int>这样的类型，会发生编译错误。
        // 为了保存int，只能使用Stream<Integer>，但这样会产生频繁的装箱、拆箱操作。
        // 为了提高效率，Java标准库提供了IntStream、LongStream和DoubleStream这三种使用基本类型的Stream，
        // 它们的使用方法和泛型Stream没有大的区别，设计这三个Stream的目的是提高运行效率
        // 将int[]数组变为IntStream:
        IntStream is = Arrays.stream(new int[] { 1, 2, 3 });
        // 将Stream<String>转换为LongStream:
        LongStream ls = List.of("1", "2", "3").stream().mapToLong(Long::parseLong);
    }
}

class NatualSupplier implements Supplier<Integer> {
    int n = 0;

    public Integer get() {
        n++;
        return n;
    }
}